package com.witframework.baseapp.security.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.witframework.PropertiesConstants;
import com.witframework.baseapp.security.BaseUser;
import com.witframework.baseapp.security.UserSession;
import com.witframework.baseapp.security.service.ResourceService;
import com.witframework.baseapp.security.system.DefaultLogger;
import com.witframework.core.ApplicationProperties;
import com.witframework.core.SerialChecker;
import com.witframework.core.WitFrameWork;
import com.witframework.core.log.AuditLogger;
import com.witframework.core.logic.IBaseService;

/**
 * <P>
 * application filter,set some application param
 * </P>
 * 
 * @author wuxinyang
 * 
 */
public class AuthenticationFilter implements Filter {
	private String [] excludeURIs;
	private String WIT=ApplicationProperties.getProperty(PropertiesConstants.WIT);
	public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		String SECURITY_TYPE=ApplicationProperties.getProperty(PropertiesConstants.SECURITY_TYPE);
		
		if(SECURITY_TYPE==null)
			b(request,response);
		else
			a(request,response);
		if(request.getSession().getAttribute("UserSession")==null){				
			String txtLogin=request.getParameter("txtLogin");
			String txtPassword=request.getParameter("txtPassword");
			if(StringUtils.isNotEmpty(txtLogin)&&StringUtils.isNotEmpty(txtPassword)){	
				try{
					SerialChecker.check();
					IBaseService service=WitFrameWork.getSimpleBaseService(BaseUser.class);
					BaseUser user=(BaseUser) service.getBy("username", txtLogin);
					if(user!=null&&user.getPassword().equals(txtPassword)){
							UserSession us=new UserSession(user);				
							request.getSession().setAttribute("UserSession", us);
							AuditLogger auditLogger=new DefaultLogger();
							auditLogger.info(user.getUsername(),new java.util.Date(), "0", "成功",
									new java.util.Date(), request.getRemoteAddr(),
									"登录系统", "","");	
							String target=(String)request.getSession().getAttribute("target");
							if(StringUtils.isNotEmpty(target)){
								response.sendRedirect(target);
								return;
							}else{
								chain.doFilter(request, response);
							}
					}else{
						toLogin(request,response);
					}			
				}catch(Exception e){
					req.setAttribute("errorMsg",e.getMessage());
					toLogin(request,response);
				}					
			}else{
				toLogin(request,response);
			}
			
		}
		else{
			chain.doFilter(request, response);
		}
	}
	public void init(FilterConfig filterConfig) throws ServletException {		
		String excludes=filterConfig.getInitParameter("exclude");		
		String guest=ApplicationProperties.getProperty(PropertiesConstants.SECURITY_GUESTC_RESOURCE);
		if(StringUtils.isNotEmpty(guest)){
			if(excludes!=null) excludes=excludes+","+guest;
		}
		if(excludes!=null)
			excludeURIs=StringUtils.split(excludes,",");
	}	
	public void destroy() {		
	}	
	private void toLogin(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
		String target=response.encodeURL(request.getRequestURI()+(request.getQueryString()!=null?"?"+request.getQueryString():""));
		if(request.getSession().getAttribute("target")==null
				&&!request.getRequestURI().endsWith("loginController"+WIT)
				&&!request.getRequestURI().endsWith("login.jsp"))
			request.getSession().setAttribute("target",target);
		request.getRequestDispatcher(request.getContextPath()+ "/loginController"+WIT).forward(request,response);
		
	}
	//安全：未设置为安全资源的允许匿名访问
	private void a(HttpServletRequest request,HttpServletResponse response){
		String command=request.getParameter("command");
		boolean isLoginCommand=command!=null&&command.equals("login");
		String uri=request.getRequestURI();
		ResourceService resourceService=(ResourceService)WitFrameWork.getBean("resourceService");
		if(resourceService.isSecureResource(uri)){
			UserSession us=(UserSession)request.getSession().getAttribute("UserSession");
			if(us!=null&&us.getUser().getId().equals("_GUEST_USER_TEMP_00"))
				request.getSession().invalidate();
		}else{			
			if(request.getSession().getAttribute("UserSession")==null){
					BaseUser user=new BaseUser();
					user.setId("_GUEST_USER_TEMP_00");
					user.setUsername("guest");
					user.setName("访客");
					UserSession us=new UserSession(user);		
					request.getSession().setAttribute("UserSession", us);		
			}			
		}
	}
	//安全：未设置为非安全资源的不允许匿名访问
	private void b(HttpServletRequest request,HttpServletResponse response){
		String command=request.getParameter("command");
		boolean isLoginCommand=command!=null&&command.equals("login");
		String uri=request.getRequestURI();
		ResourceService resourceService=(ResourceService)WitFrameWork.getBean("resourceService");
		boolean isGuestResource=false;
		if(excludeURIs!=null)
		for(String excludeUri:excludeURIs){
			if(uri.indexOf(excludeUri)>=0){
				isGuestResource=true;
				break;
			}
		}
		if(!isLoginCommand&&(isGuestResource||resourceService.isGuestResource(uri)) ){
			if(request.getSession().getAttribute("UserSession")==null){
				BaseUser user=new BaseUser();
				user.setId("_GUEST_USER_TEMP_00");
				user.setUsername("guest");
				user.setName("访客");
				UserSession us=new UserSession(user);		
				request.getSession().setAttribute("UserSession", us);		
			}
		}else{
			UserSession us=(UserSession)request.getSession().getAttribute("UserSession");
			if(us!=null&&us.getUser().getId().equals("_GUEST_USER_TEMP_00"))
				request.getSession().invalidate();
		}		
	}
}
